package hos.http.retrofit;

import static hos.http.retrofit.TypeUtil.methodError;

import android.text.TextUtils;

import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;

import hos.http.Http;
import hos.http.HttpFile;
import hos.http.HttpInterceptor;
import hos.http.HttpMethod;
import hos.http.HttpParam;

/**
 * <p>Title: HttpServiceMethod </p>
 * <p>Description:  </p>
 * <p>Company: www.mapuni.com </p>
 *
 * @author : 蔡俊峰
 * @version : 1.0
 * @date : 2024-04-22 13:48
 */
public class HttpServiceMethod<T> extends RetrofitServiceMethod<T> {

    private RetrofitRequestFactory retrofitRequestFactory;

    @Override
    public RetrofitServiceMethod<T> parse(Class<?> service, Method method) {
        retrofitRequestFactory = RetrofitRequestFactory.parseAnnotations(service, method);
        Type returnType = method.getGenericReturnType();
        if (returnType == void.class) {
            throw methodError(method, "Service methods cannot return void.");
        }
        return this;
    }

    /**
     * @noinspection unchecked
     */
    @Override
    public T invoke(Object instance, Object[] args) {
        RetrofitRequest retrofitRequest = RetrofitRequest.parseAnnotations(retrofitRequestFactory, args);
        String httpMethod = retrofitRequest.getHttpMethod();
        String url = retrofitRequest.getUrl();
        Type paresType = retrofitRequest.getParesType();
        String contentType = retrofitRequest.getContentType();
        Map<String, String> headers = retrofitRequest.getHeaders();
        List<HttpParam> urlParam = retrofitRequest.getUrlParam();
        List<HttpParam> bodyParam = retrofitRequest.getBodyParam();
        Object body = retrofitRequest.getBody();
//        Object tag = retrofitRequest.getTag();
        boolean formEncoded = retrofitRequest.isFormEncoded();
        boolean multipart = retrofitRequest.isMultipart();
//        boolean hasBody = retrofitRequest.isHasBody();
        List<HttpFile> fileList = retrofitRequest.getFileList();
        HttpInterceptor.RequestInterceptor requestInterceptor = retrofitRequest.getRequestInterceptor();
        HttpInterceptor.ExceptionInterceptor exceptionInterceptor = retrofitRequest.getExceptionInterceptor();
        HttpInterceptor.ResponseInterceptor responseInterceptor = retrofitRequest.getResponseInterceptor();
        if (TextUtils.equals(httpMethod, HttpMethod.GET)) {
            return (T) Http.get(url)
                    .contentType(contentType)
                    .addHeaderAll(headers)
                    .setType(paresType)
                    .interceptor(requestInterceptor)
                    .interceptor(exceptionInterceptor)
                    .interceptor(responseInterceptor)
                    .addQueryAll(urlParam)
                    .paramAll(bodyParam);
        }
        if (TextUtils.equals(httpMethod, HttpMethod.SOAP)) {
            String soapMethodName = retrofitRequest.getSoapMethodName();
            int soapVersion = retrofitRequest.getSoapVersion();
            String soapNameSpace = retrofitRequest.getSoapNameSpace();
            Map<String, String> soapHeaders = retrofitRequest.getSoapHeaders();
            boolean soapDotNet = retrofitRequest.isSoapDotNet();
            return (T) Http.soap(url, soapMethodName, soapNameSpace)
                    .setDotNet(soapDotNet)
                    .setType(paresType)
                    .setVersion(soapVersion)
                    .headerBody(soapHeaders)
                    .addHeaderAll(headers)
                    .interceptor(requestInterceptor)
                    .interceptor(exceptionInterceptor)
                    .interceptor(responseInterceptor)
                    .addQueryAll(urlParam)
                    .paramAll(bodyParam);
        }
        if (TextUtils.equals(httpMethod, HttpMethod.DOWNLOAD)) {
            return (T) Http.download(url)
                    .contentType(contentType)
                    .setType(paresType)
                    .addHeaderAll(headers)
                    .interceptor(requestInterceptor)
                    .interceptor(exceptionInterceptor)
                    .interceptor(responseInterceptor)
                    .addQueryAll(urlParam)
                    .paramAll(bodyParam);
        }
        return (T) Http.post(url)
                .method(httpMethod)
                .setType(paresType)
                .contentType(contentType)
                .isMultipart(multipart)
                .isFormEncoded(formEncoded)
                .addHeaderAll(headers)
                .interceptor(requestInterceptor)
                .interceptor(exceptionInterceptor)
                .interceptor(responseInterceptor)
                .addQueryAll(urlParam)
                .paramAll(bodyParam)
                .file(fileList)
                .data(body);
    }
}
